<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<!-- Line -->
<script id="VertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    attribute vec2 a_Pin;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_aM4;
    uniform mat4 u_PvM4;
    varying vec2 v_Pin;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
        v_Pin = a_Pin;
    }
</script>
<script id="FragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Sampler;
    varying vec2 v_Pin;
    void main(){
        gl_FragColor = texture2D(u_Sampler, v_Pin);
        //gl_FragColor = vec4(1,1,1,1);
    }
</script>
<script id="VertexShader1" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform float u_PointSize;
    uniform mat4 u_PvM4;
    void main(){
        gl_Position = u_PvM4 * a_Position;
        gl_PointSize = u_PointSize;
    }
</script>
<script id="FragmentShader1" type="x-shader/x-fragment">
    precision mediump float;
    void main(){
        gl_FragColor = vec4(1,1,1,1);
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import { initShaders, CreateProgram } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Geo from '../js/Poly/Geo.js'
    import Mat from '../js/Poly/Mat.js'
    import Obj3D from '../js/Poly/Obj3D.js'
    import Scene from '../js/Poly/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight - 4;

    const gl = canvas.getContext("webgl");
    //开始背景遮挡
    gl.enable(gl.DEPTH_TEST);
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    //#endregion

    //创建程序对象
    let program = CreateProgram(gl,
        document.querySelector('#VertexShader').innerText,
        document.querySelector('#FragmentShader').innerText);
    let program1 = CreateProgram(gl,
        document.querySelector('#VertexShader1').innerText,
        document.querySelector('#FragmentShader1').innerText);

    const scene = new Scene({ gl: gl });
    const perspectiveCamera = new PerspectiveCamera(45, canvas.width / canvas.height, 1, 20);
    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();
    const cameraController = new CameraController({
        canvas: canvas,
        camera: perspectiveCamera,
        pvMatrix: pvM4,
        rendEvent: draw,
    });

    const blength = 0.3;
    const nodeArr = [
        -blength, blength, 0,
        -blength, -blength, 0,
        blength, -blength, 0,
        blength, blength, 0,
    ];
    const elementArr = [
        0, 1, 2,
        0, 2, 3,
    ];
    const pinArr = [
        0, 1,
        0, 0,
        1, 0,
        1, 1,
    ];

    //饭盒矩阵
    const mi = new Matrix4();
    //冰箱矩阵
    const mb = new Matrix4();




    let img = new Image();
    img.src = './Image/Image01.jpg';
    img.onload = function () {



        let obj3D = new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': { size: 3, array: new Float32Array(nodeArr) },
                    'a_Pin': { size: 2, array: new Float32Array(pinArr) },
                },
                element: {
                    array: new Uint8Array(elementArr)
                }
            }),
            mat: new Mat({
                program: program,
                mode: ['TRIANGLES'],
                data: {
                    'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
                },
                maps: {
                    'u_Sampler': { image: img, WRAP_W: gl.LINEAR, WRAP_H: gl.LINEAR, }
                }
            }),
        });

        scene.add(obj3D);
        draw();


        let set = 0;
        let orginIndex = 0;
        setOrgin(orginIndex % 4);
        (function ani() {
            if (set >= 45) {
                set = 0;
                //顶点变换
                formatVertices(obj3D);
                //变换基点
                orginIndex++;
                setOrgin(orginIndex % 4)
            }


            set += 0.1;
            modelM4.copy(rotation(set * Math.PI / 180))
            scene.setUniform('u_ModelM4', { value: modelM4.elements });
            draw();

            requestAnimationFrame(ani);
        })();
    };



    function draw() {
        scene.setUniform('u_PvM4', { value: pvM4.elements });
        scene.draw();
    }

    function setOrgin(orginIndex) {
        let [x, y, z] = [nodeArr[orginIndex * 3 + 0], nodeArr[orginIndex * 3 + 1], nodeArr[orginIndex * 3 + 2]];
        mi.setPosition(-x, -y, -z);
        mb.setPosition(x, y, z);
    }

    function rotation(ang) {
        let s = (Math.sin(ang * 8 + Math.PI / 2) + 1) / 2;
        return mb.clone()
            .multiply(new Matrix4().makeRotationZ(ang))
            .scale(new Vector3(s, s, s))
            .multiply(mi);
    }

    function formatVertices(obj3D) {
        for (let i = 0; i < nodeArr.length; i += 3) {
            const node = new Vector3(nodeArr[i], nodeArr[i + 1], nodeArr[i + 2]).applyMatrix4(modelM4);
            nodeArr[i] = node.x;
            nodeArr[i + 1] = node.y;
            nodeArr[i + 2] = node.z;
        }
        obj3D.geo.setData('a_Position', { array: new Float32Array(nodeArr) })
    }



</script>

</html>